const jwt = require('jsonwebtoken');
const User = require('../models/User');
const { logger } = require('../utils/logger');

/**
 * JWT认证中间件
 * 验证请求头中的JWT令牌
 */
const authenticateToken = async (req, res, next) => {
  try {
    // 从请求头获取令牌
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      return res.status(401).json({
        success: false,
        message: '访问被拒绝，需要认证令牌',
        error_code: 'NO_TOKEN'
      });
    }

    // 验证令牌
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    
    // 检查是否为调试用户
    if (decoded.userId === 'debug_user_123' || decoded.user_id === 'debug_admin') {
      // 为调试用户创建虚拟用户对象
      const debugUser = {
        _id: decoded.user_id || decoded.userId || 'debug_user_123',
        email: decoded.email || 'debug@example.com',
        isAdmin: decoded.isAdmin || true,
        membershipLevel: 'admin',
        membership_level: 'admin', // requireRole中间件使用这个字段
        role: 'admin',
        isEmailVerified: true,
        isPhoneVerified: true
      };
      req.user = debugUser;
      req.token = token;
      return next();
    }
    
    // 检查用户是否存在且处于活跃状态
    const userId = decoded.user_id || decoded.userId;
    logger.debug('认证中间件: 查找用户ID:', userId);
    const user = await User.findById(userId);
    logger.debug('认证中间件: 找到用户:', user ? '是' : '否');
    if (!user) {
      return res.status(401).json({
        success: false,
        message: '无效的认证令牌，用户不存在',
        error_code: 'INVALID_USER'
      });
    }

    // 将用户信息添加到请求对象中
    req.user = user;
    req.token = token;
    
    next();
  } catch (error) {
    logger.error('JWT认证失败:', error);
    
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({
        success: false,
        message: '无效的认证令牌',
        error_code: 'INVALID_TOKEN'
      });
    }
    
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({
        success: false,
        message: '认证令牌已过期',
        error_code: 'TOKEN_EXPIRED'
      });
    }
    
    return res.status(500).json({
      success: false,
      message: '认证过程中发生错误',
      error_code: 'AUTH_ERROR'
    });
  }
};

/**
 * 可选认证中间件
 * 如果提供了令牌则验证，否则继续执行
 */
const optionalAuth = async (req, res, next) => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      // 没有令牌，继续执行但不设置用户信息
      return next();
    }

    // 有令牌，尝试验证
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    const user = await User.findById(decoded.userId);
    
    if (user) {
      req.user = user;
      req.token = token;
    }
    
    next();
  } catch (error) {
    // 令牌无效，但不阻止请求继续
    logger.warn('可选认证失败:', error.message);
    next();
  }
};

/**
 * 会员等级验证中间件
 * 验证用户是否达到指定的会员等级
 */
const requireMembershipLevel = (requiredLevel) => {
  const levelHierarchy = {
    'bronze': 1,
    'silver': 2,
    'gold': 3,
    'platinum': 4
  };

  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({
        success: false,
        message: '需要用户认证',
        error_code: 'AUTH_REQUIRED'
      });
    }

    const userLevel = levelHierarchy[req.user.membership_level] || 0;
    const requiredLevelValue = levelHierarchy[requiredLevel] || 0;

    if (userLevel < requiredLevelValue) {
      return res.status(403).json({
        success: false,
        message: `需要${requiredLevel}会员等级或更高`,
        error_code: 'INSUFFICIENT_MEMBERSHIP_LEVEL',
        required_level: requiredLevel,
        current_level: req.user.membership_level
      });
    }

    next();
  };
};

/**
 * 邮箱验证检查中间件
 * 验证用户邮箱是否已验证
 */
const requireEmailVerification = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({
      success: false,
      message: '需要用户认证',
      error_code: 'AUTH_REQUIRED'
    });
  }

  if (!req.user.email_verified) {
    return res.status(403).json({
      success: false,
      message: '需要验证邮箱后才能访问此功能',
      error_code: 'EMAIL_NOT_VERIFIED'
    });
  }

  next();
};

/**
 * 手机号验证检查中间件
 * 验证用户手机号是否已验证
 */
const requirePhoneVerification = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({
      success: false,
      message: '需要用户认证',
      error_code: 'AUTH_REQUIRED'
    });
  }

  if (!req.user.phone_verified) {
    return res.status(403).json({
      success: false,
      message: '需要验证手机号后才能访问此功能',
      error_code: 'PHONE_NOT_VERIFIED'
    });
  }

  next();
};

/**
 * 管理员权限检查中间件
 * 检查用户是否具有管理员权限
 */
const requireAdmin = async (req, res, next) => {
  try {
    if (!req.user) {
      return res.status(401).json({
        success: false,
        message: '需要用户认证',
        error_code: 'AUTH_REQUIRED'
      });
    }

    // 检查用户的membership_level是否为admin
    logger.debug('检查管理员权限，用户ID:', req.user.user_id, '会员等级:', req.user.membership_level);
    
    if (req.user.membership_level !== 'admin') {
      logger.warn('用户不是管理员，拒绝访问');
      return res.status(403).json({
        success: false,
        message: '需要管理员权限',
        error_code: 'ADMIN_REQUIRED'
      });
    }
    
    logger.info('管理员权限验证通过');

    // 将管理员信息添加到请求对象
    req.admin = req.user;
    next();
  } catch (error) {
    logger.error('管理员权限检查失败:', error);
    return res.status(500).json({
      success: false,
      message: '权限检查过程中发生错误',
      error_code: 'PERMISSION_CHECK_ERROR'
    });
  }
};

/**
 * 用户自身资源访问检查
 * 确保用户只能访问自己的资源
 */
const requireSelfOrAdmin = (userIdParam = 'userId') => {
  return async (req, res, next) => {
    try {
      if (!req.user) {
        return res.status(401).json({
          success: false,
          message: '需要用户认证',
          error_code: 'AUTH_REQUIRED'
        });
      }

      const targetUserId = parseInt(req.params[userIdParam]);
      const currentUserId = req.user.user_id;

      // 如果是访问自己的资源，允许通过
      if (targetUserId === currentUserId) {
        return next();
      }

      // 检查是否为管理员
      const db = require('../config/database');
      const adminCheckSql = 'SELECT admin_id FROM admins WHERE user_id = ? AND is_active = true';
      const [adminRows] = await db.execute(adminCheckSql, [currentUserId]);

      if (adminRows.length > 0) {
        req.admin = adminRows[0];
        return next();
      }

      // 既不是自己的资源，也不是管理员
      return res.status(403).json({
        success: false,
        message: '无权访问此资源',
        error_code: 'ACCESS_DENIED'
      });
    } catch (error) {
      logger.error('资源访问权限检查失败:', error);
      return res.status(500).json({
        success: false,
        message: '权限检查过程中发生错误',
        error_code: 'PERMISSION_CHECK_ERROR'
      });
    }
  };
};

/**
 * 令牌刷新检查
 * 检查令牌是否即将过期，如果是则提示刷新
 */
const checkTokenExpiry = (req, res, next) => {
  try {
    if (!req.token) {
      return next();
    }

    const decoded = jwt.decode(req.token);
    const currentTime = Math.floor(Date.now() / 1000);
    const timeUntilExpiry = decoded.exp - currentTime;

    // 如果令牌在1小时内过期，添加刷新提示
    if (timeUntilExpiry < 3600) {
      res.set('X-Token-Refresh-Suggested', 'true');
      res.set('X-Token-Expires-In', timeUntilExpiry.toString());
    }

    next();
  } catch (error) {
    logger.error('令牌过期检查失败:', error);
    next(); // 不阻止请求继续
  }
};

/**
 * 角色权限验证中间件
 * 验证用户是否具有指定角色之一
 */
const requireRole = (allowedRoles) => {
  return async (req, res, next) => {
    try {
      if (!req.user) {
        return res.status(401).json({
          success: false,
          message: '需要用户认证',
          error_code: 'AUTH_REQUIRED'
        });
      }

      // 检查用户角色是否在允许的角色列表中
      const userRole = req.user.membership_level;
      
      // admin角色可以访问所有资源
      if (userRole === 'admin') {
        req.admin = req.user;
        return next();
      }
      
      // ops_manager角色映射到admin权限
      if (userRole === 'ops_manager' && allowedRoles.includes('ops_manager')) {
        req.admin = req.user;
        return next();
      }
      
      // 检查是否在允许的角色列表中
      if (!allowedRoles.includes(userRole)) {
        logger.warn('用户角色权限不足', {
          user_id: req.user.user_id,
          user_role: userRole,
          required_roles: allowedRoles
        });
        
        return res.status(403).json({
          success: false,
          message: `需要以下角色之一: ${allowedRoles.join(', ')}`,
          error_code: 'INSUFFICIENT_ROLE',
          required_roles: allowedRoles,
          current_role: userRole
        });
      }
      
      next();
    } catch (error) {
      logger.error('角色权限检查失败:', error);
      return res.status(500).json({
        success: false,
        message: '权限检查过程中发生错误',
        error_code: 'ROLE_CHECK_ERROR'
      });
    }
  };
};

module.exports = {
  authenticateToken,
  optionalAuth,
  requireMembershipLevel,
  requireEmailVerification,
  requirePhoneVerification,
  requireAdmin,
  requireRole,
  requireSelfOrAdmin,
  checkTokenExpiry,
  verifyToken: authenticateToken // 导出verifyToken作为authenticateToken的别名
};